<template>
  <low-app-box>
    <a-row :class="['low-app-layout', {'dev-mode': devMode}]">
      <!-- 左侧菜单 -->
      <a-col class="left">
        <a-row class="search-box">
          <a-col :span="devMode ? 20 : 24">
            <a-input class="search-input" v-model="searchKeyword" placeholder="搜索" allowClear>
              <a-icon slot="prefix" type="search"/>
            </a-input>
          </a-col>
          <a-col v-if="devMode" :span="4" style="text-align: right;line-height: 34px;">
            <a-dropdown :trigger="['click']">
              <a-button type="primary" shape="circle" icon="plus" size="small" title="添加"/>
              <a-menu slot="overlay">
                <a-menu-item key="create-group" @click="onCreateGroup">
                  <a-icon type="folder-add"/>
                  <span>新建分组</span>
                </a-menu-item>
                <!-- <a-menu-divider/>-->
                <!-- <a-menu-item key="link-cgform" @click="onOpenLinkModal('cgform')">关联Online表单</a-menu-item>-->
                <!-- <a-menu-item key="link-desform" @click="onOpenLinkModal('desform')">关联设计器表单</a-menu-item>-->
              </a-menu>
            </a-dropdown>
          </a-col>
        </a-row>
        <div v-if="searchKeyword && menuListFiltered.length === 0" class="left-menu-empty">
          <a-empty :image="PRESENTED_IMAGE_SIMPLE" description="搜索结果为空"/>
        </div>
        <div v-else-if="!devMode && menuListFiltered.length === 0" class="left-menu-empty">
          <a-empty :image="PRESENTED_IMAGE_SIMPLE" description="无菜单"/>
        </div>
        <low-app-left-menu
            v-else
            :menuList="menuListFiltered"
            :devMode="devMode"
            @menu-name="onMenuNameChange"
            @settingMenuClick="onSettingMenuClick"/>
      </a-col>
      <!-- 右侧页面 -->
      <a-col class="right">
        <div class="right-title">
          <div class="title">
            <a-breadcrumb>
              <!-- 编辑模式下的首页 -->
              <a-breadcrumb-item v-if="devMode">
                <router-link :to="`/app/${appId}`">
                  <a-icon type="home"/>
                </router-link>
              </a-breadcrumb-item>
              <a-breadcrumb-item>
                {{ currentMenuName || appInfo.appName }}
              </a-breadcrumb-item>
            </a-breadcrumb>
          </div>
        </div>
        <div class="right-content">
          <div v-if="isRootRoute" class="link-box">
            <home-button backColor="#eef7ff" @click="onOpenLinkModal('cgform')">
              <template #icon>
                <a-icon type="cloud" theme="twoTone"/>
              </template>
              <span>新建Online表单</span>
            </home-button>
            <home-button backColor="#fff9e4" @click="onOpenLinkModal('desform')">
              <template #icon>
                <a-icon type="file-text" theme="twoTone" two-tone-color="#FFC300"/>
              </template>
              <span>新建设计器表单</span>
            </home-button>
            <home-button backColor="#ffefe7" @click="onOpenLinkModal('graphreport')">
              <template #icon>
                <a-icon type="pie-chart" theme="twoTone" two-tone-color="#eb2f96"/>
              </template>
              <span>新建Online图表</span>
            </home-button>
            <home-button backColor="#eeffc0" @click="onOpenLinkModal('cgreport')">
              <template #icon>
                <a-icon type="carry-out" theme="twoTone" two-tone-color="#53CF00"/>
              </template>
              <span>新建Online报表</span>
            </home-button>
          </div>
          <router-view ref="routerView" v-else/>
        </div>
      </a-col>

      <low-app-link-modal ref="linkModal" @ok="initApp"/>
      <low-app-menu-move-group-modal ref="moveGroupModal" @ok="initApp"/>
    </a-row>
  </low-app-box>
</template>

<script>
import {mapActions} from 'vuex'
import LowAppBox from './LowAppBox'

import {deleteAction, getAction, httpAction, postAction} from '@api/manage'
import LowAppLeftMenu from '../menu/LowAppLeftMenu'
import LowAppLinkModal from '../modules/LowAppLinkModal'
import LowAppMenuMoveGroupModal from '../modules/LowAppMenuMoveGroupModal'
import HomeButton from '../components/HomeButton'
import LowAppMenuType from '../constant/LowAppMenuType'
import LowAppStoreMixins from '../mixins/LowAppStoreMixins'
import {aspectAroundFunction, sleep} from '@/utils/util'
import {Empty} from 'ant-design-vue'

export default {
  name: 'LowAppLayout',
  mixins: [LowAppStoreMixins],
  components: {LowAppBox, LowAppLinkModal, LowAppLeftMenu, LowAppMenuMoveGroupModal, HomeButton},
  data() {
    return {
      loading: false,
      // 搜索关键字
      searchKeyword: '',
      url: {
        queryById: '/online/lowApp/queryById',
        queryDetail: '/online/lowApp/queryDetail',
        menu: {
          edit: '/online/lowAppMenu/edit',
          delete: '/online/lowAppMenu/delete',
          createGroup: '/online/lowAppMenu/createGroup',
          orderToUp: '/online/lowAppMenu/orderToUp',
          orderToDown: '/online/lowAppMenu/orderToDown',
        },
      },
      currentMenuName: '',
      PRESENTED_IMAGE_SIMPLE: Empty.PRESENTED_IMAGE_SIMPLE,
    }
  },
  computed: {
    // 是否是APP根路由
    isRootRoute() {
      return this.$route.name === 'low-app-@appId'
    },
    // 筛选后的 menuList
    menuListFiltered() {
      // 根据 searchKeyword 筛选
      if (this.searchKeyword) {
        let filter = []
        this.menuList.forEach(menu => {
          if (menu.type === LowAppMenuType.GROUP.type) {
            let children = menu.children.filter(child => child.menuName.includes(this.searchKeyword))
            if (children.length > 0) {
              filter.push({...menu, children})
            }
          } else if (menu.menuName.includes(this.searchKeyword)) {
            filter.push(menu)
          }
        })
        return filter
      }
      return this.menuList
    },
  },
  watch: {
    $route: {
      immediate: true,
      handler() {
        this.addReloadListenerByRoute()
      },
    },
    appId: {
      immediate: true,
      handler() {
        this.initApp()
      },
    },
  },
  created() {
  },
  methods: {
    ...mapActions(['setLowAppInfo']),
    // 根据 appId 初始化应用
    initApp() {
      this.loading = true
      getAction(this.url.queryDetail, {
        id: this.appId,
      }).then((res) => {
        if (res.success) {
          // 在这里set this.menuList 和 this.appInfo
          this.setLowAppInfo(res.result)
          // // 限制标题不超过5个字符长度，防止过长显示混乱
          let title = this.appInfo.appName
          // if (title.length > 5) {
          //   title = title.slice(0, 5) + '…'
          // }
          this.changeTitle(title)
        } else {
          if (res.code === 404) {
            this.$router.replace({path: '/404'})
          } else {
            this.changeTitle('加载失败')
            this.$error({title: '加载失败', content: res.message})
          }
        }
      }).finally(() => this.loading = false)
    },

    changeTitle(title) {
      let projectTitle = 'Jeecg-Boot 企业级低代码平台'
      if (title == null) {
        document.title = this.appInfo.appName + ' · ' + projectTitle
      } else {
        document.title = title + ' · ' + this.appInfo.appName + ' · ' + projectTitle
      }
    },

    /** 根据当前路由，添加刷新页面的监听事件 */
    async addReloadListenerByRoute() {
      await this.$nextTick()
      if (!this.$refs.routerView || !this.$refs.routerView.$refs) {
        return
      }
      const routerView = this.$refs.routerView
      // 切面编程回调函数
      let callback = (event) => {
        this.initApp()
        return event.proceed()
      }
      // 如果当前页面是列表页面，就切面loadData方法，用于刷新菜单
      if (this.$route.name === 'low-app-@appId-list-desform') {
        // 表单设计器
        aspectAroundFunction(routerView, 'loadData', callback)
      } else if (this.$route.name === 'low-app-@appId-list-cgreport') {
        // Online报表
        aspectAroundFunction(routerView, 'loadData', callback)
      } else if (this.$route.name === 'low-app-@appId-list-graphreport') {
        // Online图表
        aspectAroundFunction(routerView, 'loadData', callback)
      } else if (this.$route.name === 'low-app-@appId-list-cgform') {
        // Online表单
        aspectAroundFunction(routerView, 'loadData', callback)
      } else if (this.$route.name === 'low-app-@appId-menu-recycle-bin') {
        // 回收站
        aspectAroundFunction(routerView, 'loadData', callback)
      }
    },

    // 新建分组
    onCreateGroup() {
      this.doAddOrEditGroup()
    },

    // 打开关联弹窗
    onOpenLinkModal(type) {
      // this.$refs.linkModal.add(type)
      if (type === 'cgform') {
        this.$router.push({name: 'low-app-@appId-list-cgform'})
        this.doOpenAddModal()
      } else if (type === 'desform') {
        this.$router.push({name: 'low-app-@appId-list-desform'})
        this.doOpenAddModal('handleAddDesign')
      } else if (type === 'cgreport') {
        this.$router.push({name: 'low-app-@appId-list-cgreport'})
        this.doOpenAddModal()
      } else if (type === 'graphreport') {
        this.$router.push({name: 'low-app-@appId-list-graphreport'})
        this.doOpenAddModal()
      }
    },

    // 打开页面的新增弹窗，提供打开方法
    async doOpenAddModal(name = 'handleAdd') {
      let count = 0
      const getFn = async () => {
        await this.$nextTick()
        let fn = null
        if (this.$refs.routerView) {
          fn = this.$refs.routerView[name]
        }
        if (typeof fn === 'function') {
          return fn
        } else if (++count === 10) {
          return null
        } else {
          await sleep(10)
          return getFn()
        }
      }
      let fn = await getFn()
      fn && fn()
    },

    // 点击事件：菜单setting
    onSettingMenuClick(e, record) {
      if (e.key === 'edit') {
        this.$refs.linkModal.edit(record)
      } else if (e.key === 'move-group') {
        this.$refs.moveGroupModal.show(record)
      } else if (e.key === 'delete') {
        this.doDeleteMenu(record)
      } else if (e.key === 'group-rename') {
        this.doAddOrEditGroup(record)
      } else if (e.key === 'order-to-up') {
        this.doMenuOrderTo(this.url.menu.orderToUp, record)
      } else if (e.key === 'order-to-down') {
        this.doMenuOrderTo(this.url.menu.orderToDown, record)
      } else {
        this.$message.warning('暂未开放!')
      }
    },
    // 创建或修改菜单分组
    doAddOrEditGroup(record) {
      this.$JPrompt({
        title: record ? '重命名' : '创建分组',
        defaultValue: record ? record.menuName : '',
        placeholder: '请输入分组名称',
        rule: [{required: true, message: '分组名称不能为空！'}],
        onOkAsync: (event) => {
          let method = 'post', url = this.url.menu.createGroup
          if (record) {
            method = 'put'
            url = this.url.menu.edit
          }

          event.target.showLoading()
          httpAction(url, {
            id: record ? record.id : null,
            appId: this.appId,
            menuName: event.value,
          }, method).then((res) => {
            if (res.success) {
              this.$message.success(res.message)
              event.target.forceClose()
              this.initApp()
            } else {
              this.$message.warning(res.message)
            }
          }).finally(() => event.target.hideLoading())
        },
      })
    },
    // 删除菜单
    doDeleteMenu(record) {
      if (Array.isArray(record.children) && record.children.length > 0) {
        this.$message.warning('有子菜单的分组不能删除！')
        return
      }
      this.$confirm({
        title: '删除',
        content: '确定要删除吗？',
        onOk: () => {
          deleteAction(this.url.menu.delete, {id: record.id}).then(a => {
            this.initApp()
            if (this.$route.name === 'low-app-@appId-menu-recycle-bin') {
              // 回收站同步刷新
              this.$refs.routerView.loadData()
            }
          })
        },
      })
    },
    // 菜单排序更改
    doMenuOrderTo(url, record) {
      postAction(url, {
        id: record.id,
      }).then(res => {
        if (res.success) {
          this.initApp()
        } else {
          this.$message.warning(res.message)
        }
      })
    },
    // 更改了当前菜单名称，修改标题
    onMenuNameChange(menuName) {
      this.currentMenuName = menuName == null ? this.appInfo.appName : menuName
      this.changeTitle(menuName)
    },

  },
}
</script>

<style lang="less" scoped>
/* 应用详情样式 */
.low-app-layout {
  display: flex;
  min-height: 800px;
  height: calc(100vh - 130px);

  .left, .right {
    position: relative;
  }

  .left {
    width: 210px;
    min-width: 210px;

    // 搜索框样式
    .search-box {
      width: 100%;
      height: 50px;
      padding: 10px;
      background-color: white;

      .search-input {
        width: 100%;

        /deep/ .ant-input {
          border-radius: 25px;
        }
      }
    }

    .left-menu,
    .left-menu-empty {
      width: 100%;
      height: 100%;
      overflow: hidden auto;
    }

    .left-menu-empty {
      background-color: #ffffff;
      border-right: 1px solid #e8e8e8;
    }

    /deep/ .low-app-menu-item.ant-menu-item,
    /deep/ .low-app-menu-group .ant-menu-submenu-title {

      // 菜单右侧setting图标样式
      .low-app-menu-setting {
        position: absolute;
        top: 0;
        right: 6px;
        display: none;
      }

      &:hover {

        // 鼠标移动到菜单上时，显示setting图标
        .low-app-menu-setting {
          display: block;
        }
      }
    }

  }

  .right {
    flex: auto;
    overflow: auto;

    .right-title {
      display: flex;
      align-items: center;
      padding: 0 16px;
      background-color: #FFFFFF;
      border-bottom: 1px solid #e8e8e8;

      .title {
        font-size: 16px;
        display: inline-block;
        flex: 1;
        padding: 16px 0;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        font-weight: 500;
      }
    }

    .right-content {
      padding: 8px;
      position: relative;
    }

    .link-box {
      position: absolute;
      top: 200px;
      left: 24%;
    }

  }

  // 开发下的样式
  &.dev-mode {
    .left {
      /deep/ .low-app-menu-group {
        // 鼠标移动到子菜单上时，隐藏小箭头
        & .ant-menu-submenu-title:hover .ant-menu-submenu-arrow {
          display: none;
        }
      }
    }
  }

}
</style>
<style lang="less">
/*.tab-layout-router-view {*/
/*  margin: 0;*/
/*}*/

// 全局 lowApp scope，只有在 app 下才生效的样式
[data-low-app] {
  // 隐藏功能测试等操作
  [data-dev-action='功能测试'],
  [data-dev-action='配置地址'],
  [data-dev-action='生成视图'],
  [data-dev-action='视图管理'],
  [data-dev-action='索引工具'],
  [data-dev-action='发起流程'],
  [data-dev-action='表单数据'] {
    display: none !important;

    & + .ant-divider-vertical {
      display: none !important;
    }
  }
}
</style>